/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author pipo
 */

package mainGame;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Map {
  
    protected List<Trainer> gameItems;
    protected List<MapElement> mapElements;
    protected List<Trap> traps;
    private int mapSizeX, mapSizeY;
    private String userName;
    private Player player;
    private boolean newGame;
    private int selection;
    

public Map(int X, int Y, String userName , int selection , boolean newGame )
{
    gameItems = new ArrayList<Trainer>();
    mapElements = new ArrayList<MapElement>();
    traps = new ArrayList<Trap>();
    this.mapSizeX = X;
    this.mapSizeY = Y;
    this.userName = userName;
    this.newGame = newGame;
    this.addMapElements();
    if(newGame) initNewGame(selection);
    this.selection = selection;

}

public void initNewGame(int selection)
{
    
    this.player = new Player(0,0, this.userName, 0);
    this.gameItems.add(player);
    addGameItems(selection);
}
    
public void addMapElements()
{
this.addMapElement( 0 , 10, 1 ); 
this.addMapElement( 0 , 11, 1 ); 
this.addMapElement( 0 , 12, 1 ); 
this.addMapElement( 0 , 13, 1 ); 
this.addMapElement( 0 , 14, 1 ); 
this.addMapElement( 0 , 15, 1 ); 
this.addMapElement( 0 , 16, 1 ); 
this.addMapElement( 0 , 17, 1 ); 
this.addMapElement( 0 , 18, 1 ); 
this.addMapElement( 0 , 20, 1 ); 
this.addMapElement( 1 , 10, 1 ); 
this.addMapElement( 1 , 11, 1 ); 
this.addMapElement( 1 , 12, 1 ); 
this.addMapElement( 1 , 13, 1 ); 
this.addMapElement( 1 , 14, 1 ); 
this.addMapElement( 1 , 15, 1 ); 
this.addMapElement( 1 , 16, 1 ); 
this.addMapElement( 1 , 18, 1 ); 
this.addMapElement( 1 , 19, 1 ); 
this.addMapElement( 2 , 0, 1 ); 
this.addMapElement( 2 , 1, 1 ); 
this.addMapElement( 2 , 2, 1 ); 
this.addMapElement( 2 , 3, 1 ); 
this.addMapElement( 2 , 4, 1 ); 
this.addMapElement( 2 , 5, 1 ); 
this.addMapElement( 2 , 6, 1 ); 
this.addMapElement( 2 , 7, 1 );
this.addMapElement(2 , 10 , 1 );
this.addMapElement( 2 , 11, 1 ); 
this.addMapElement( 2 , 12, 1 ); 
this.addMapElement( 2 , 13, 1 ); 
this.addMapElement( 2 , 14, 1 ); 
this.addMapElement( 2 , 15, 1 ); 
this.addMapElement( 2 , 16, 1 ); 
this.addMapElement( 2 , 17, 1 ); 
this.addMapElement( 2 , 18, 1 ); 
this.addMapElement( 2 , 19, 1 ); 
this.addMapElement( 3 , 10, 1 ); 
this.addMapElement( 3 , 11, 1 ); 
this.addMapElement( 3 , 18, 1 ); 
this.addMapElement( 3 , 19, 1 ); 
this.addMapElement( 3 , 20, 1 ); 
this.addMapElement( 4 , 3, 2 ); 
this.addMapElement( 4 , 4, 2 ); 
this.addMapElement( 4 , 5, 2 ); 
this.addMapElement( 4 , 6, 2 ); 
this.addMapElement( 4 , 10, 1 ); 
this.addMapElement( 4 , 11, 1 ); 
this.addMapElement( 4 , 19, 1 ); 
this.addMapElement( 4 , 20, 1 ); 
this.addMapElement( 5 , 3, 2 ); 
this.addMapElement( 5 , 4, 2 ); 
this.addMapElement( 5 , 5, 2 ); 
this.addMapElement( 5 , 6, 2 ); 
this.addMapElement( 5 , 10, 1 ); 
this.addMapElement( 5 , 11, 1 ); 
this.addMapElement( 5 , 12, 1 ); 
this.addMapElement( 5 , 13, 2 ); 
this.addMapElement( 5 , 14, 2 ); 
this.addMapElement( 5 , 15, 2 ); 
this.addMapElement( 5 , 19, 1 ); 
this.addMapElement( 5 , 20, 1 ); 
this.addMapElement( 6 , 3, 2 ); 
this.addMapElement( 6 , 4, 2 ); 
this.addMapElement( 6 , 5, 2 ); 
this.addMapElement( 6 , 6, 2 ); 
this.addMapElement( 6 , 10, 1 ); 
this.addMapElement( 6 , 11, 1 ); 
this.addMapElement( 6 , 13, 2 ); 
this.addMapElement( 6 , 14, 2 ); 
this.addMapElement( 6 , 15, 2 ); 
this.addMapElement( 6 , 19, 1 ); 
this.addMapElement( 6 , 20, 1 ); 
this.addMapElement( 7 , 3, 2 ); 
this.addMapElement( 7 , 4, 2 ); 
this.addMapElement( 7 , 5, 2 ); 
this.addMapElement( 7 , 6, 2 ); 
this.addMapElement( 7 , 13, 2 ); 
this.addMapElement( 7 , 14, 2 ); 
this.addMapElement( 7 , 15, 2 ); 
this.addMapElement( 7 , 19, 1 ); 
this.addMapElement( 7 , 20, 1 ); 
this.addMapElement( 8 , 20, 1 ); 
this.addMapElement( 8 , 19, 1 ); 
this.addMapElement( 8 , 15, 2 ); 
this.addMapElement( 8 , 14, 2 ); 
this.addMapElement( 8 , 13, 2 ); 
this.addMapElement( 9 , 4, 1 ); 
this.addMapElement( 9 , 5, 1 ); 
this.addMapElement( 9 , 6, 1 ); 
this.addMapElement( 9 , 7, 1 ); 
this.addMapElement( 9 , 19, 1 ); 
this.addMapElement( 9 , 20, 1 ); 
this.addMapElement( 10 , 20, 1 ); 
this.addMapElement( 10 , 19, 1 ); 
this.addMapElement( 11 , 19, 1 ); 
this.addMapElement( 11 , 20, 1 ); 
this.addMapElement( 12 , 5, 1 ); 
this.addMapElement( 12 , 4, 1 ); 
this.addMapElement( 13, 4 , 1);
this.addMapElement( 13 , 5, 1 ); 
this.addMapElement( 13 , 8, 1 ); 
this.addMapElement( 13 , 9, 1 ); 
this.addMapElement( 13 , 12, 1 ); 
this.addMapElement( 13 , 13, 1 ); 
this.addMapElement( 13 , 19, 1 ); 
this.addMapElement( 13 , 20, 1 ); 
this.addMapElement( 14 , 20, 1 ); 
this.addMapElement( 14 , 19, 1 ); 
this.addMapElement( 14 , 13, 1 ); 
this.addMapElement( 14 , 12, 1 ); 
this.addMapElement( 14 , 9, 1 ); 
this.addMapElement( 14 , 8, 1 ); 
this.addMapElement( 14 , 7, 1 ); 
this.addMapElement( 14 , 5, 1 ); 
this.addMapElement( 14 , 4, 1 ); 
this.addMapElement( 15 , 7, 1 ); 
this.addMapElement( 15 , 8, 1 ); 
this.addMapElement( 15 , 9, 1 ); 
this.addMapElement( 15 , 12, 1 ); 
this.addMapElement( 15 , 13, 1 ); 
this.addMapElement( 15 , 19, 1 ); 
this.addMapElement( 15 , 20, 1 ); 
this.addMapElement( 16 , 20, 1 ); 
this.addMapElement( 16 , 19, 1 ); 
this.addMapElement( 16 , 7, 1 ); 
this.addMapElement( 17 , 7, 1 ); 
this.addMapElement( 17 , 19, 1 ); 
this.addMapElement( 17 , 20, 1 ); 
this.addMapElement( 18 , 20, 1 ); 
this.addMapElement( 18 , 19, 1 ); 
this.addMapElement( 18 , 7, 1 ); 
this.addMapElement( 18 , 4, 1 ); 
this.addMapElement( 18 , 3, 1 ); 
this.addMapElement( 18 , 2, 1 ); 
this.addMapElement( 19 , 2, 1 ); 
this.addMapElement( 19 , 3, 1 ); 
this.addMapElement( 19 , 4, 1 ); 
this.addMapElement( 19 , 7, 1 ); 
this.addMapElement( 19 , 8, 1 ); 
this.addMapElement( 19 , 9, 1 ); 
this.addMapElement( 19 , 12, 1 ); 
this.addMapElement( 19 , 13, 1 ); 
this.addMapElement( 19 , 19, 1 ); 
this.addMapElement( 19 , 20, 1 ); 
this.addMapElement( 20 , 20, 1 ); 
this.addMapElement( 20 , 19, 1 ); 
this.addMapElement( 20 , 13, 1 ); 
this.addMapElement( 20 , 12, 1 ); 
this.addMapElement( 20 , 9, 1 ); 
this.addMapElement( 20 , 8, 1 ); 
this.addMapElement( 20 , 7, 1 ); 
this.addMapElement( 20 , 4, 1 ); 
this.addMapElement( 20 , 3, 1 ); 
this.addMapElement( 20 , 2, 1 ); 
this.addMapElement( 21 , 2, 1 ); 
this.addMapElement( 21 , 3, 1 ); 
this.addMapElement( 21 , 4, 1 ); 
this.addMapElement( 21 , 7, 1 ); 
this.addMapElement( 21 , 19, 1 ); 
this.addMapElement( 21 , 20, 1 ); 
this.addMapElement( 22 , 20, 1 ); 
this.addMapElement( 22 , 19, 1 ); 
this.addMapElement( 22 , 7, 1 ); 
this.addMapElement( 23 , 19, 1 ); 
this.addMapElement( 23 , 20, 1 ); 
this.addMapElement( 24 , 20, 1 ); 
this.addMapElement( 24 , 19, 1 ); 
this.addMapElement( 24 , 18, 1 ); 
this.addMapElement( 24 , 17, 1 ); 
this.addMapElement( 24 , 16, 1 ); 
this.addMapElement( 24 , 15, 1 ); 
this.addMapElement( 25 , 20, 1 ); 
this.addMapElement( 25 , 19, 1 ); 
this.addMapElement( 25 , 18, 1 ); 
this.addMapElement( 25 , 17, 1 ); 
this.addMapElement( 25 , 16, 1 ); 
this.addMapElement( 25 , 15, 1 ); 
this.addMapElement( 25 , 14, 1 ); 
this.addMapElement( 25 , 13, 1 ); 
this.addMapElement( 25 , 12, 1 ); 
this.addMapElement( 25 , 11, 1 ); 
this.addMapElement( 25 , 10, 1 ); 
this.addMapElement( 25 , 9, 1 ); 
this.addMapElement( 25 , 8, 1 ); 
this.addMapElement( 25 , 7, 1 ); 
this.addMapElement( 25 , 6, 1 ); 
this.addMapElement( 25 , 5, 1 ); 
this.addMapElement( 25 , 4, 1 ); 
this.addMapElement( 25 , 3, 1 ); 
this.addMapElement( 26 , 3, 1 ); 
this.addMapElement( 26 , 4, 1 ); 
this.addMapElement( 26 , 5, 1 ); 
this.addMapElement( 26 , 6, 1 ); 
this.addMapElement( 26 , 7, 1 ); 
this.addMapElement( 26 , 8, 1 ); 
this.addMapElement( 26 , 9, 1 ); 
this.addMapElement( 26 , 10, 1 ); 
this.addMapElement( 26 , 11, 1 ); 
this.addMapElement( 26 , 12, 1 ); 
this.addMapElement( 26 , 13, 1 ); 
this.addMapElement( 26 , 14, 1 ); 
this.addMapElement( 26 , 15, 1 ); 
this.addMapElement( 26 , 16, 1 ); 
this.addMapElement( 26 , 17, 1 ); 
this.addMapElement( 26 , 18, 1 ); 
this.addMapElement( 26 , 19, 1 ); 
this.addMapElement( 26 , 20, 1 );     
    
}

public void addMapElement(int X , int Y , int type)
{
    
    MapElement elem = new MapElement(X,Y,type);
    this.mapElements.add(elem);
    
}

public void addItemToMap(Trainer item)
{
    this.gameItems.add(item);
}

public void addTrapToMap(Trap t)
{
    this.traps.add(t);
}

private void addGameItems(int startSelection)
{  
    
    //first 3 enemies = 1 pokemon each
    //5 enemies = 2 pokemons each
    //3 trap pokemons -> other starting pokemons
    //final boss = 3 pokemons
    //1 starting pokemon
    
    
    //FIRE POKEMONS 
    Pokemon FancyBabyFox = new Pokemon(80, 30 , 110 , 2 , 1 , "Fancy Baby Fox");
    Pokemon Charmeleon = new Pokemon(80 , 25, 105 , 2 ,1, "Charmeleon");
    Pokemon FirePonyThing = new Pokemon(90, 20 , 100 , 2, 1 , "Fire Pony Thing");
    Pokemon BurningPenguin = new Pokemon(75 , 35 , 130 , 2 ,1 , "Burning Penguin");
    Pokemon TeddyDog = new Pokemon(85 , 20 , 120 , 2, 1 , "Teddy Dog");
       
    //ELECTRIC POKEMONS  
    Pokemon HornyMouse = new Pokemon(85, 10 , 85 , 1 , 1 , "Horny Mouse");
    Pokemon Meaw = new Pokemon(80, 10 , 95 , 1 , 1, "Meaw"); 
    Pokemon Pikachu = new Pokemon(90 , 15, 95, 1, 1, "Pikachu");
    Pokemon Wappy = new Pokemon(105, 5 , 85, 1, 1, "Wappy"); 
    Pokemon Fakechu = new Pokemon(95, 15, 110 , 1 , 1, "Fakechu");
    
    //EARTH POKEMONS  
    Pokemon Boner = new Pokemon(65 , 30 , 125, 3 , 1, "Boner"); 
    Pokemon KarateKid = new Pokemon(70 , 35 , 110,  3 , 1 , "Karate Kid" );
    Pokemon FatMutantPacman = new Pokemon(65 , 35 , 110 , 3 , 1 , "Fat Mutant Pacman" );
    Pokemon NinjaMonkey = new Pokemon(70 , 35 , 115 , 3 , 1,  "Ninja Monkey" );
    Pokemon Onix = new Pokemon(65 , 45 , 140 , 3, 1, "Onix"); 
    
    //WATER POKEMONS
    Pokemon Squirtle = new Pokemon(75, 30 , 110 , 4, 1 , "Squirtle");
    Pokemon WetMouse = new Pokemon(70 , 30 , 105 , 4 , 1 , "Wet Mouse");
    Pokemon Skypi = new Pokemon(75 , 30 , 110 , 4, 1 ,"Skypi");
    Pokemon Wormmy = new Pokemon(70 , 35 , 125 , 4 , 1 , "Wormmy");
    Pokemon Hypno = new Pokemon(80, 25 , 110 , 4 , 1 , "Hypno");
   
    //LEVEL-UP POKEMONS
    HornyMouse.updateAttributes(1);
    TeddyDog.updateAttributes(2);
    KarateKid.updateAttributes(2);
    Wormmy.updateAttributes(2);
    FirePonyThing.updateAttributes(3);
    Fakechu.updateAttributes(3);
    FatMutantPacman.updateAttributes(3);
    Meaw.updateAttributes(3);
    FancyBabyFox.updateAttributes(4);
    NinjaMonkey.updateAttributes(4);
    WetMouse.updateAttributes(4);
    BurningPenguin.updateAttributes(5);
    Wappy.updateAttributes(5);
    Hypno.updateAttributes(5);
    
    //TRAPS
    Trap TPikachu = new Trap(0,5, Pikachu);
    Trap TCharmeleon = new Trap(3,7,Charmeleon);
    Trap TSquirtle = new Trap(9 , 10 , Squirtle ); 
    Trap TOnix = new Trap(6,17, Onix);    

    
    //ADD PLAYER STARTING POKEMON
    if(startSelection == 0)
        player.addPokemon(Pikachu);
    else if(startSelection == 1)
        player.addPokemon(Charmeleon);
    else if(startSelection == 2)
        player.addPokemon(Squirtle);
    else
        player.addPokemon(Onix);
    
//    //ENEMY TRAINERS
    Trainer t1 = new Trainer(0,8,"Trainer1"); 
    Trainer t2 = new Trainer(7,10,"Trainer2");
    Trainer t3 = new Trainer(10,12,"Trainer3");
    Trainer t4 = new Trainer(11,15,"Trainer4");
    Trainer t5 = new Trainer(14,14,"Trainer5");
    Trainer t6 = new Trainer(19,14,"Trainer6");
    Trainer t7 = new Trainer(19,10,"Trainer7");
    Trainer t8 = new Trainer(14,10,"Trainer8");
    Trainer t9 = new Trainer(20,5,"Boss");
//   
//    //DISTRIBUTE POKEMONS TO ENEMY TRAINERS     
    t1.addPokemon(Boner);
    t2.addPokemon(Skypi);
    t3.addPokemon(HornyMouse);
    t4.addPokemon(TeddyDog);
    t4.addPokemon(KarateKid);
    t5.addPokemon(Wormmy);
    t5.addPokemon(FirePonyThing);
    t6.addPokemon(Fakechu);
    t6.addPokemon(FatMutantPacman);
    t7.addPokemon(FancyBabyFox);
    t7.addPokemon(Meaw);
    t8.addPokemon(NinjaMonkey);
    t8.addPokemon(WetMouse);
    t9.addPokemon(BurningPenguin);
    t9.addPokemon(Wappy);
    t9.addPokemon(Hypno);
//    
//    //ADD ITEMS TO MAP
    this.gameItems.add(t1); this.gameItems.add(t2); this.gameItems.add(t3); this.gameItems.add(t4);
    this.gameItems.add(t5); this.gameItems.add(t6); this.gameItems.add(t7); this.gameItems.add(t8);
    this.gameItems.add(t9);
//    
//    //ADD TRAPS TO MAP
    this.traps.add(TPikachu); this.traps.add(TCharmeleon); this.traps.add(TSquirtle); this.traps.add(TOnix);
    this.traps.remove(startSelection);
    //OBSTACLES

}

public int enemyCollision(int direction)
{
    //returns the index of the enemy if collision happens, returns -1 otherwise
    
    int X = this.player.tryMoveXCoor(direction);
    int Y = this.player.tryMoveYCoor(direction);

    for(GameItem i : this.gameItems)
    {
        if(i != this.player)
        {
            if(i.getXCoor() == X && i.getYCoor() == Y)
            {
                
                return gameItems.indexOf(i); //enemy trainer collision
            }
            
        }
        
    }
    
    
    return -1; //no collision
        
}


public int obstacleCollision(int direction)
{
    int X = this.player.tryMoveXCoor(direction);
    int Y = this.player.tryMoveYCoor(direction);
    
    for(MapElement e : this.mapElements)
    {
        if(e.getXCoor() == X && e.getYCoor() == Y)
        {
                return e.getType(); //1 for water 2 for obstacle            
        }
        
    }
    return 0; //no collision will happen, player can move
}

public int trapCollision(int direction)
{
    int X = this.player.tryMoveXCoor(direction);
    int Y = this.player.tryMoveYCoor(direction);
    
    for(Trap t : this.traps)
    {
        if(t.getXCoor() == X && t.getYCoor() == Y)
        {
            return this.traps.indexOf(t); //returns the index of the trap if player collided with one
            
        }
        
    }
    
    return -1;
    
}

public void movePlayer(int direction)
{
    this.player.move(direction);  
}


public boolean playerHitBoundary(int direction)
{
        //direction 1: left, 2:up, 3:right, 4:bottom
        //upper left is the (0,0)    
    int X = this.player.getXCoor();
    int Y = this.player.getYCoor();
    
    return ( (X == 0 && direction == 1) || 
           (X == this.mapSizeX && direction == 3) || 
           (Y == 0 && direction == 2) || 
           (Y == this.mapSizeY && direction == 4) );
}

public void deleteEnemyTrainer(Trainer enemy , boolean isTrap)
{
    if(isTrap)
    {
        this.traps.remove(enemy);
    }
    else
    {
        this.gameItems.remove(enemy);
    }
}

public Trap returnTrap(int index)
{
    return this.traps.get(index);
}

public Trainer returnTrainer(int index)
{
    return this.gameItems.get(index);
}

public int noOfItems()
{
    return this.gameItems.size();   
}


public int noOfTraps()
{
    return this.traps.size();
    
}
public int playerXCoor()
{
    return this.player.getXCoor();
    
}

public int playerYCoor()
{
    return this.player.getYCoor();
    
}

public String pokemonList(int index)
{   
    return this.gameItems.get(index).pokemonList();   
}

public Player returnPlayer()
{
    return (Player) this.gameItems.get(0);
    
}

public int getSizeX()
{
    
    return this.mapSizeX;
    
}


public int getSizeY()
{
    
    return this.mapSizeY;
    
}

public String getUserName()
{
    return this.player.getName();
    
}

public void setPlayer(Player p)
{
    this.player = p;
}

public int getSelection()
{
    return this.selection;
}

}